/*
 * Zombinoes: Peter Mosher, Michael Pitts
 * TCSS 491 - Computational Worlds
 * Project 1
 */

package physics;

import graphics.InternalNode;
import graphics.Node;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Stores the physical objects in the simulation, moves them over time and 
 * resolves any collisions that result. 
 * @author Michael Pitts
 *
 */
public class PhysicalCollection {
	
	private static final int RUN = 10;
	
	/** My mobile objects. */
	private final List<PhysicsObject> my_objects = new ArrayList<PhysicsObject>();
	
	/** My immobile, inverse mass == 0, objects. */
	private final List<PhysicsObject> my_immobiles = new ArrayList<PhysicsObject>();
	
	/** The graphics objects. */
	private final List<Node> my_graphics = new ArrayList<Node>();
	
	public PhysicalCollection(final Collection<PhysicsObject> the_objects) {
		for (PhysicsObject obj : the_objects) {
			if (obj.inverseMass == 0) {
				my_immobiles.add(obj);
			} else {
				my_objects.add(obj);
			}
			if (obj.renderable != null) my_graphics.add(obj.renderable);
		}
	}
	
	public InternalNode getGraphics() {
		return new InternalNode(Collections.unmodifiableCollection(my_graphics));
	}
	
	public void crank(final float the_time) {
		for (PhysicsObject obj : my_objects) {
			obj.updateState(the_time);
		}
		int runs = 0;
		boolean collide = true;
		CollisionInfo info;
		while (collide && runs < RUN) {
			runs++;
			collide = false;
			for (int i = 0; i < my_objects.size(); i++) {
				for (PhysicsObject immobile : my_immobiles) {
					info = null;
					info = immobile.getCollision(my_objects.get(i), the_time);
					if (info != null) {
						collide = true;
						immobile.resolveCollision(my_objects.get(i), info);
					}
				}
				for (int j = i + 1; j < my_objects.size(); j++) {
					info = null;
					info = my_objects.get(j).getCollision(my_objects.get(i), the_time);
					if (info != null) {
						collide = true;
						my_objects.get(j).resolveCollision(my_objects.get(i), info);
					}
				}
			}
		}
		for (PhysicsObject obj : my_objects) obj.updateRenderable();
	}
}
